def header(package_name: str, classname: str) -> str:
    ret = "use fsm::{EnumTag, Machine};\r\nuse std::sync::{Arc, Mutex};\r\n\r\n"

    return ret


def states_header() -> str:
    return ''


def states_repr(machine, classname, parent_state=None) -> str:
    """
    目前仅处理没有子状态的情况
    """

    struct_name = f'{classname}State'

    ret = '#[derive(Copy, Clone, PartialEq)]\r\n'
    ret += f'enum {struct_name} {{\r\n'

    last_state = None
    for state in machine.states:
        ret += f'    {state.name},\r\n'
        last_state = state

    
    ret += '}\r\n\r\n'


    impl_str = f'''impl EnumTag for {struct_name} {{
    fn tag_number(&self) -> usize {{
        *self as usize
    }}

    fn max_tag_number() -> usize {{
        {struct_name}::{last_state.name} as usize
    }}
}}'''

    ret += impl_str

    return ret


def states_footer() -> str:
    return ""


def transitions_header() -> str:
    return "\r\n"


def transitions_repr(machine, classname) -> str:
    event_set = set()

    for t in machine.transitions:
        event_set.add(t.trigger)
    
    events = list(event_set)

    state_name = f'{classname}State'
    event_name = f'{classname}Event'
    last_event = events[-1]

    event_str = f'''#[derive(Copy, Clone)]
enum {event_name} {{\r\n'''
    for e in events:
        event_str += f'    {e},\r\n'

    
    event_str += '}\r\n'

    impl_str = f'''impl EnumTag for FsmEvent {{
    fn tag_number(&self) -> usize {{
        *self as usize
    }}
    fn max_tag_number() -> usize {{
        {event_name}::{last_event} as usize
    }}
}}
'''

    event_str += f'\r\n{impl_str}'

    ret = event_str

    ret += '\r\n'

    ret += f"""struct FsmContainer<'a> {{
    val: Arc<Mutex<i32>>,
    machine: Machine<'a, {state_name}, {event_name}, Arc<Mutex<i32>>>
}}\r\n\r\n"""

    fsm_declaration = f"""impl <'a>FsmContainer<'a> {{
    fn new(init_val: i32) -> Self {{
        let c = Arc::new(Mutex::new(init_val));
        let mut machine = Machine::new({state_name}::{machine.transitions[0].from_state}, c.clone());

"""
    for t in machine.transitions:
        fsm_declaration += f'''        machine.add_transition({state_name}::{t.from_state}, {event_name}::{t.trigger}, {state_name}::{t.to_state}, |_,_, ctx| {{let mut g = ctx.lock().unwrap();}});
'''
    fsm_declaration += "\r\n        FsmContainer {val: c, machine}\r\n"

    fsm_declaration += '    }\r\n}\r\n\r\n'

    ret += fsm_declaration

    return ret


def transitions_footer() -> str:
    return "\r\n"


def context_annotation() -> str:
    return ''


def class_declaration_start(classname: str) -> str:
    return ''


def companion_declaration_start() -> str:
    return ''


def states_declaration(state_names) -> str:
    return ''


def events_declaration(event_names) -> str:
    return ''


def companion_declaration_end() -> str:
    return ''


def transition_methods_repr(methods) -> str:
    return ''


def class_declaration_end():
    return ''

